void main(void)
{

void (*theKernel)(int zero, int arch, unsigned int params); 

//定义一个函数指针theKernel,其中第一个参数zero:0           

// arch:机器ID ,由于芯片类型很多,内核为了辨别芯片而定义的机器ID，其中2440芯片的ID号是362,

/* params :tag参数位置,这里我们的tag起始地址=0x30000100*/

  //1.初始化串口0，打印内核信息

  uart0_init();                                             //调用serial.h头文件里的uart0_init()
  puts(“uart0 init OK\r\n”);                                //打印uart0初始化  

  //2.从  nand   flash  里 把 内 核 复 制 到  SDRAM  中 

  puts(“copy  kernel  from  nand\r\n”);                  //打印内核复制
  nand_read((0x60000+64),0X30008000,0X200000);              //烧写2MB,多烧写点避免出错       

/*

0x60000+64:表示内核在nand(存储)地址上位置,
0X30008000:内核在sdram(运行)地址上位
0X200000:内核长度2MB
因为Flash上存的内核格式是：uImage(64B头部(header)  + 真正的内核 )
在uboot界面中输入mtd命令可以看到:

              kernel分区位于 nand的0X00060000~0x00260000

所以在nand中真正的内核地址=0x60000+64,
在uboot界面中输入boot命令可以看到:
            Data Size:    1848656 Bytes =1.8 MB

            Load Address: 30008000
所以内核目的地址=0X30008000
长度=1.8MB

*/

  //3. 设  置  T  A  G  参  数

 puts(“set  boot  params\r\n”);                  //打印设置参数信息
 setup_start_tag (void);                      //在0X30000100地址保存start_tag数据，
 setup_memory_tags (void);                      //保存memory_tag数据,让内核知道内存多大
 setup_commandline_tag (“boottargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0”);  
 /*保存命令行bootargs参数,让内核知道根文件系统位置在/dev/mtdblock3,指定开机运行第一个脚本/linuxrc,指定打印串口0*/
 setup_end_tag (void);                            //初始化tag结构体结束

 
 //4. 跳 转 执 行

   puts(“boot   kernel\r\n”);                      //打印启动内核
   theKernel = (void (*)(int, int, unsigend int))0x30008000;
    // 设置theKernel地址=0x30008000,用于后面启动内核
   theKernel(0,362,0x300000100);        //362:机器ID，  0x300000100: params(tag)地址



/*传递参数跳转执行到0x30008000启动内核,           */
/*相当于: mov r0,#0                             */
/*ldr r1,=362                                  */
/*ldr r2,= 0x300000100                         */
/*mov pc,#0x30008000                           */


  puts(“kernel  ERROR\r\n”);                  //打印内核启动出错

}
